import { groupBy, isEmpty } from 'lodash-es'

import { multiply, subtract } from './calculate'

/**
 * @typedef {Object} filterListProps
 * @property {Array} [dataSource] 数据源
 * @property {{}} [searchParams] 搜索参数
 * @property {Array<string>} [stringFieldList] 根据字符串过滤，【包含】
 * @property {Array<string>} [idFieldList] 根据id过滤，【全匹配】
 */

/**
 * 根据搜索条件过滤数据
 * @param {filterListProps} props
 * @returns
 */
const filterList = props => {
  const { dataSource = [], searchParams = {}, stringFieldList = [], idFieldList = [], isTree } = props
  const dataMap = {}
  dataSource.forEach(item => {
    dataMap[item.id] = item
  })
  const filterData = dataSource.filter(item => {
    const includeString = stringFieldList.every(
      stringField =>
        searchParams[stringField] === undefined ||
        searchParams[stringField] === null ||
        item[stringField].includes(searchParams[stringField]),
    )
    const includeId = idFieldList.every(
      idField =>
        searchParams[idField] === undefined ||
        searchParams[idField] === null ||
        item[idField] === searchParams[idField],
    )
    return includeString && includeId
  })
  if (isTree) {
    filterData.map(({ parentId }) => {
      if (String(parentId) !== '0' && !filterData.find(({ id }) => id === parentId)) {
        filterData.push(dataMap[parentId])
      }
    })
  }
  return filterData
}

/**
 * @typedef {Object} listToTreeProps
 * @property {Array} [dataSource] 数据源
 * @property {string} [topId] 顶层id，默认0
 * @property {string} [idField] 后端唯一键，默认id
 * @property {string} [parentIdField] 后端父id唯一键，默认parentId
 */

/**
 * 将平铺的数据转换成树结构
 * @param {listToTreeProps} props
 * @returns
 */
export const listToTree = props => {
  const { dataSource, topId = '0', idField = 'id', parentIdField = 'parentId' } = props
  const groupByParentId = groupBy(dataSource, parentIdField)
  const tree = groupByParentId[0]
  if (isEmpty(tree)) {
    return []
  }
  const deepTransform = parentId => {
    groupByParentId[parentId].map(item => {
      const { [idField]: id } = item
      if (groupByParentId[id]) {
        item.children = groupByParentId[id]
        deepTransform(id)
      }
    })
  }
  deepTransform(topId)
  return tree
}

/**
 * 1、根据搜索条件过滤
 * 2、分页
 * @param {filterListProps} props
 * @returns
 */
export const listToPage = props => {
  const { dataSource, searchParams, stringFieldList = ['name'], idFieldList = [] } = props
  const filterData = filterList({
    dataSource,
    searchParams,
    stringFieldList,
    idFieldList,
  })
  const current = searchParams.current
  const pageSize = searchParams.pageSize
  const total = filterData.length
  const list = filterData.slice(multiply(subtract(current, 1), pageSize), multiply(current, pageSize))
  return { total, current, pageSize, list }
}

/**
 * 1、根据搜索条件过滤
 * 2、将平铺的数据转换成树结构
 * 3、分页
 * @param {filterListProps} props
 * @returns
 */
export const listToPageTree = props => {
  const { dataSource, searchParams, stringFieldList = ['name'], idFieldList = [] } = props
  const filterData = filterList({
    dataSource,
    searchParams,
    stringFieldList,
    idFieldList,
    isTree: true,
  })
  const tree = listToTree({ dataSource: filterData })
  const current = searchParams.current
  const pageSize = searchParams.pageSize
  const total = tree.length
  const list = tree.slice(multiply(subtract(current, 1), pageSize), multiply(current, pageSize))
  return { total, current, pageSize, list }
}

/**
 * @typedef {Object} handleTreeDataProps
 * @property {Array} [dataSource] 数据源
 * @property {string} [childrenField] children字段名，默认children
 * @property {function} [callback] 处理方法
 */

/**
 * 处理树结构数据，对每个节点进行处理
 * @param {handleTreeDataProps} props
 */
export const handleTreeData = props => {
  const { dataSource, childrenField = 'children', callback } = props
  dataSource.forEach(item => {
    if (!isEmpty(item[childrenField])) {
      handleTreeData({
        dataSource: item[childrenField],
        callback,
      })
    }
    callback(item)
  })
  return dataSource
}

/**
 * @typedef {Object} getIdListProps
 * @property {Array} [dataSource] 数据源
 * @property {string} [childrenField] children字段名，默认children
 * @property {string} [fieldName] 字段名，默认id
 * @property {string | number} [fieldValue] 字段值
 */

/**
 * 根据某个字段获取所在树的所有该字段数组，默认获取id
 * @param {getIdListProps} props
 * @returns
 */
export const getIdList = props => {
  const { dataSource, childrenField = 'children', fieldName = 'id', fieldValue: id } = props
  const idMap = {}
  const deepGenerate = (_list, value) => {
    _list.forEach(item => {
      const _value = [...value]
      const { [fieldName]: id, [childrenField]: children } = item
      _value.push(id)
      idMap[id] = _value
      if (!isEmpty(children)) {
        deepGenerate(children, _value)
      }
    })
  }
  deepGenerate(dataSource, [])

  return idMap[id] || []
}

/**
 * @typedef {Object} getItemFromTreeProps
 * @property {Array} [dataSource] 数据源
 * @property {string} [childrenField] children字段名，默认children
 * @property {string} [fieldName] 字段名，默认id
 * @property {string | number} [fieldValue] 字段值
 */

/**
 * 根据某个字段获取对象，默认id
 * @param {getItemFromTreeProps} props
 * @returns
 */
export const getItemFromTree = props => {
  const { dataSource, childrenField = 'children', fieldName: idField = 'id', fieldValue: id } = props
  const itemMap = {}
  const deepGenerate = _list => {
    _list.forEach(item => {
      const { [idField]: id, [childrenField]: children } = item
      itemMap[id] = item
      if (!isEmpty(children)) {
        deepGenerate(children)
      }
    })
  }
  deepGenerate(dataSource)
  return itemMap[id]
}
